package sys

/*******************************************************************************
Copyright:cloud
Author:cloudapex@126.com
Version:1.0
Date:2020-06-12
Description: 系统.角色
*******************************************************************************/
import (
	"context"
	"permis/api/api"
	"permis/api/cache"
	"permis/model"

	gpc "gitee.com/cloudapex/protos/comm/pb"
	gpb "gitee.com/cloudapex/protos/permis/pb"

	"gitee.com/cloudapex/ulern/util"
)

/*
 * 描述: 角色列表
 * 方法: Simple
 *********************************************************************/
func (this *Server) RoleList(ctx context.Context, req *gpb.RoleListReq) (*gpb.RoleListRes, error) {
	m := &model.Role{
		CoId:   req.CoId,
		Name:   req.Name,
		Kind:   req.Kind,
		State:  req.State,
		Remark: req.Remark,
	}
	if err := util.Convert(&m.Sorte, req.Sorte); err != nil {
		return nil, api.ConvertError("", err)
	}
	if err := util.Convert(&m.Pager, req.Pager); err != nil {
		return nil, api.ConvertError("", err)
	}

	total, items, err := m.Find()
	if err != nil {
		return nil, api.DBError("", err)
	}
	roles := []*gpb.Role{}
	if err := util.Convert(&roles, items); err != nil {
		return nil, api.ConvertError("", err)
	}
	return &gpb.RoleListRes{Total: total, List: roles}, nil
}

/*
 * 描述: 角色简表
 * 方法: Simple
 *********************************************************************/
func (this *Server) RoleLabs(ctx context.Context, req *gpb.RoleLabsReq) (*gpb.RoleLabsRes, error) {
	items, err := (&model.Role{
		CoId:  req.CoId,
		Kind:  req.Kind,
		Name:  req.Name,
		State: req.State,
	}).FindLabs()
	if err != nil {
		return nil, api.DBError("", err)
	}

	lables := []*gpb.RoleLable{}
	if err := util.Convert(&lables, items); err != nil {
		return nil, api.ConvertError("", err)
	}
	return &gpb.RoleLabsRes{List: lables}, nil
}

/*
 * 描述: 新增角色
 * 方法: Simple
 *********************************************************************/
func (this *Server) RoleAdd(ctx context.Context, req *gpb.RoleAddReq) (*gpc.IdResponse, error) {
	m := model.Role{
		CoId:   req.CoId,
		Name:   req.Name,
		Kind:   req.Kind,
		Order:  req.Order,
		State:  req.State,
		Remark: req.Remark,
	}
	if _, err := m.Create(); err != nil {
		return nil, api.DBError("", err)
	}
	return &gpc.IdResponse{Id: m.Id}, nil
}

/*
 * 描述: 编辑角色
 * 方法: Simple
 *********************************************************************/
func (this *Server) RoleUpd(ctx context.Context, req *gpb.RoleUpdReq) (*gpc.UnResponse, error) {
	m := model.Role{
		Id:     req.Id,
		Name:   req.Name,
		Kind:   req.Kind,
		Order:  req.Order,
		State:  req.State,
		Remark: req.Remark,
	}
	// 更新记录, 允许后面的几个字段被重置为默认值
	if _, err := m.Update(req.Id, "order", "remark"); err != nil {
		return nil, api.DBError("", err)
	}
	return &gpc.UnResponse{}, nil
}

/*
 * 描述: 删除角色
 * 方法: Simple
 *********************************************************************/
func (this *Server) RoleDel(ctx context.Context, req *gpc.IdRequest) (*gpc.UnResponse, error) {
	eff, err := (&model.Role{}).Delete(req.Id)
	if err != nil {
		return nil, api.DBError("", err)
	}
	if eff == 0 {
		return nil, api.FoundError("此角色不存在")
	}

	// 影响的哪些用户
	uIds, err := (&model.UserRole{RoleId: req.Id}).FindIds()
	if err != nil {
		this.Error("UserChoose.FindIds err:%v", err)
	}
	// for user cache
	util.Goroutine("HandUserRoles", func() { // 更新用户角色缓存
		if err := cache.HandUserRoles(uIds, false); err != nil {
			this.Error("UserChoose.HandUserRoles err:%v", err)
		}
	})

	if _, err := (&model.UserRole{}).Delete(0, req.Id); err != nil {
		return nil, api.DBError("", err)
	}
	if _, err := (&model.GroupRole{}).Delete(0, req.Id); err != nil {
		return nil, api.DBError("", err)
	}
	if _, err := (&model.RolePower{}).Delete(req.Id, 0); err != nil {
		return nil, api.DBError("", err)
	}

	return &gpc.UnResponse{}, nil
}

/*
 * 描述: 获取角色权限Ids
 * 方法: Simple
 *********************************************************************/
func (this *Server) RoleChoice(ctx context.Context, req *gpc.IdRequest) (*gpb.RoleChoiceRes, error) {
	ids, err := (&model.RolePower{RoleId: req.Id}).FindIds()
	if err != nil {
		return nil, api.DBError("", err)
	}
	return &gpb.RoleChoiceRes{Ids: ids}, nil
}

/*
 * 描述: 修改角色权限Ids
 * 方法: Simple
 *********************************************************************/
func (this *Server) RoleChoose(ctx context.Context, req *gpb.RoleChooseReq) (*gpc.UnResponse, error) {
	if has, err := (&model.Role{Id: req.RId}).Load(); !has || err != nil {
		return nil, api.DBError("此角色不存在", err)
	}
	if vry, err := (&model.Power{}).VerifyIds(req.PIds); !vry || err != nil {
		return nil, api.DBError("权限验证失败", err)
	}

	// 更新角色与权限的关联
	m := model.RolePower{}
	if _, err := m.Delete(req.RId, 0); err != nil {
		return nil, api.DBError("角色权限操作失败", err)
	}
	if err := m.Insert(req.RId, req.PIds); err != nil {
		return nil, api.DBError("角色权限更新失败", err)
	}

	util.Goroutine("HandRouteRoles", func() { // 更新路由角色缓存
		if err := cache.HandRouteRoles(req.CoId, req.PIds); err != nil {
			this.Error("RoleChoose.HandRouteRoles err:%v", err)
		}
	})
	return &gpc.UnResponse{}, nil
}
